﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace MyImaginaryFriends_Redux.Screens.GamePlayScreen_Classes
{
    class PlayerEntity
    {
        #region Variables
        Texture2D t2d_SpritePic;//Temporary for collision checking and stuff.

        Texture2D t2d_DarknessOverlay;
        public MoveDirection PushDirection;

        Vector2 v2_DarknessOrigin;

        Animation.SpriteAnimation Mallory;
        SpriteEffects spriteEffect = SpriteEffects.None;

        bool b_hasSoundPlayed = false;
        bool b_hasSound2Played = false;

        private TileCollision TTPCollision;//temporary
        public TileCollision GetTTPCollision()
        {
            return TTPCollision;
        }

        State GrabGamescreenState;

        #region Audio Variables
        private SoundEffect se_DoorOpenOne;
        private SoundEffect se_DoorOpenTwo;
        private SoundEffect se_Death;
        private SoundEffect se_LampOn;
        private SoundEffect se_LampOff;//Not In Yet
        private SoundEffect se_Latch;
        private SoundEffect se_LockedDoor;
        private SoundEffect se_WeightSwitch;
        private SoundEffect se_DespawnCry;
        private SoundEffect se_SpawnReadyCry;
        private SoundEffect se_CannotSummon;

        private Song song_HeartBeatModerate;
        private Song song_HeartBeatFast;
        private Song song_AmbiantBGM;

        private SoundEffectInstance sei_DoorOpenOne;
        private SoundEffectInstance sei_DoorOpenTwo;
        private SoundEffectInstance sei_Death;
        private SoundEffectInstance sei_LampOn;
        private SoundEffectInstance sei_LampOff;//*
        private SoundEffectInstance sei_Latch;
        private SoundEffectInstance sei_LockedDoor;
        public SoundEffectInstance sei_WeightSwitch;
        private SoundEffectInstance sei_DespawnCry;
        private SoundEffectInstance sei_SpawnReadyCry;
        private SoundEffectInstance sei_CannotSummon;
        #endregion

        private const float cf_MaxHealthState = 100.0f;

        public float f_SummonTimer;    //How long the friend has been out. 

        const float f_MaxSummonTimer = 900.0f;   //The longest a friend can stay out.

        public float f_HealthState
        {
            get { return f_healthState; }
            set { f_healthState = value; }
        }
        float f_healthState;

        public bool b_IsHit
        {
            get { return b_isHit; }
            set { b_isHit = value; }
        }
        bool b_isHit;

        public bool b_IsOnGround
        {
            get { return b_isOnGround; }
            set { b_isOnGround = value; }
        }
        bool b_isOnGround;

        public bool b_IsAlive
        {
            get { return b_isAlive; }
            set { b_isAlive = value; }
        }
        bool b_isAlive;

        public Vector2 v2_Position
        {
            get { return v2_position; }
            set { v2_position = value; }
        }
        Vector2 v2_position;

        public Vector2 v2_Velocity
        {
            get { return v2_velocity; }
            set { v2_velocity = value; }
        }
        Vector2 v2_velocity;

        public Vector2 v2_StayHerePosition
        {
            get { return v2_stayHerePosition; }
            set { v2_stayHerePosition = value; }
        }
        Vector2 v2_stayHerePosition;

        public float f_movementX;
        private float f_movementY;

        public float f_previousBottom;

        private bool b_isJumping;
        private bool b_wasJumping;
        private float f_jumpTime;

        bool b_HeartBeatFast;
        bool b_HeartBeatNormal;
        bool b_Ambiance;

        #region Player To Friend Command Booleans
        //--
        public bool b_HasMusicBox = false;
        public bool b_HasLampKey = false;
        bool b_HasBirdcageKey = false;
        bool b_HasTelescopeKey = false;

        public bool b_hasKnifeKey = false;

        public bool b_CanEndGame = false;

        public bool b_friendTimeOut = false;

        public bool b_RequestSummon = false;
        public bool b_RequestDeSummon = false;
        public bool b_RequestFollow = false;
        public bool b_RequestStay = false;

        public bool b_RequestAbilityOneActivate = false;
        public bool b_RequestAbilityOneStop = false;

        public bool GetRequestSummon()
        {
            return b_RequestSummon;
        }

        public bool GetRequestDeSummon()
        {
            return b_RequestDeSummon;
        }

        public bool GetRequestFollow()
        {
            return b_RequestFollow;
        }

        public bool GetRequestStay()
        {
            return b_RequestStay;
        }

        public bool GetRequestAbilityOneActive()
        {
            return b_RequestAbilityOneActivate;
        }

        public bool GetRequestAbilityOneStop()
        {
            return b_RequestAbilityOneStop;
        }

        #endregion

        #region Player to Map Commands

        public bool b_isCollidingWith_BedTile = false;

       

        public bool b_isRoomAGateActive = true;

        private bool b_RequestPauseMenuOpen = false;
        public bool GetSetRequestPauseMenuOpen
        {
            get { return b_RequestPauseMenuOpen; }
            set { b_RequestPauseMenuOpen = value; }
        }

        public bool b_IsCollidingWithPushableObject = false;

        #region Starting Room Booleans

        bool b_isCollidingWith_StartToHallway = false;

        public bool b_RequestActivate_Door_StartToHallway
        {
            get { return b_requestActivate_StartToHall; }
            set { b_requestActivate_StartToHall = value; }
        }
        bool b_requestActivate_StartToHall;

        #endregion

        #region Hallway Booleans

        public bool b_isCollidingWith_HallwayToStart = false;

        public bool b_RequestActivate_Door_HallwayToStart
        {
            get { return b_requestActivate_HallToStart; }
            set { b_requestActivate_HallToStart = value; }
        }
        bool b_requestActivate_HallToStart;

        public bool b_isCollidingWith_Hallway_to_A = false;

        public bool b_RequestActivate_HallToA
        {
            get { return b_requestActivate_HallToA; }
            set { b_requestActivate_HallToA = value; }
        }
        bool b_requestActivate_HallToA;

        public bool b_isCollidingWith_Hallway_To_B = false;

        public bool b_RequestActivate_HallToB
        {
            get { return b_requestActivate_HallToB; }
            set { b_requestActivate_HallToB = value; }
        }
        bool b_requestActivate_HallToB;

        public bool b_isCollidingWith_Hallway_To_D = false;

        public bool b_RequestActivate_HallToD
        {
            get { return b_requestActivate_HallToD; }
            set { b_requestActivate_HallToD = value; }
        }
        bool b_requestActivate_HallToD;

        #endregion

        #region RoomA

        public bool b_isCollidingWith_A_To_Hallway = false;

        public bool b_RequestActivate_AToHall
        {
            get { return b_requestActivate_AToHall; }
            set { b_requestActivate_AToHall = value; }
        }
        bool b_requestActivate_AToHall;

        public bool b_isCollidingWith_A_Trigger_To_Gate = false;

        public bool b_RequestActivate_GateTrigger_BlockRoom2ToRoomA
        {
            get { return b_requestActivate_GateTrigger_BlockRoom2ToRoomA; }
            set { b_requestActivate_GateTrigger_BlockRoom2ToRoomA = value; }
        }
        bool b_requestActivate_GateTrigger_BlockRoom2ToRoomA;

        public bool b_isCollidingWith_A_To_PaintRoom1 = false;

        public bool b_RequestActivate_AToPaintRm1
        {
            get { return b_requestActivate_AToPaintRm1; }
            set { b_requestActivate_AToPaintRm1 = value; }
        }
        bool b_requestActivate_AToPaintRm1;

        #endregion

        #region PaintingRoom1

        public bool b_isCollidingWith_PaintingRoom1_To_RoomA = false;

        public bool b_RequestActivate_PaintingRoom1_To_RoomA
        {
            get { return b_requestActivate_PaintingRoom1_To_RoomA; }
            set { b_requestActivate_PaintingRoom1_To_RoomA = value; }
        }
        bool b_requestActivate_PaintingRoom1_To_RoomA;

        public bool b_isCollidingWith_PaintingRoom1_To_PaintingRoom2 = false;

        public bool b_RequestActivate_PaintingRoom1_To_PaintingRoom2
        {
            get { return b_requestActivate_PaintingRoom1_To_PaintingRoom2; }
            set { b_requestActivate_PaintingRoom1_To_PaintingRoom2 = value; }
        }
        bool b_requestActivate_PaintingRoom1_To_PaintingRoom2;

        #endregion 

        #region PaintingRoom2
        public bool b_isCollidingWith_PaintingRoom2_To_PaintingRoom1 = false;//The one that links back to the painting room, not the one that falls

        public bool b_RequestActivate_PaintingRoom2_to_PaintingRoom1
        {
            get { return b_requestActivate_PaintingRoom2_To_PaintingRoom1; }
            set { b_requestActivate_PaintingRoom2_To_PaintingRoom1 = value; }
        }
        bool b_requestActivate_PaintingRoom2_To_PaintingRoom1;

        public bool b_isCollidingWith_PaintingRoom2_To_PaintingRoom3 = false;

        public bool b_RequestActivate_PaintingRoom2_To_PaintingRoom3
        {
            get { return b_requestActivate_PaintingRoom2_to_PaintingRoom3; }
            set { b_requestActivate_PaintingRoom2_to_PaintingRoom3 = value; }
        }
        bool b_requestActivate_PaintingRoom2_to_PaintingRoom3;
        #endregion

        #region PaintingRoom3
        public bool b_isCollidingWith_PaintingRoom3_To_PaintingRoom1 = false;

        public bool b_RequestActivate_PaintingRoom3_To_PaintingRoom1
        {
            get { return b_requestActivate_PaintingRoom3_To_PaintingRoom1; }
            set { b_requestActivate_PaintingRoom3_To_PaintingRoom1 = value; }
        }
        bool b_requestActivate_PaintingRoom3_To_PaintingRoom1;

        public bool b_isCollidingWith_PaintingRoom3_To_GateRoom = false;

        public bool b_RequestActivate_PaintingRoom3_To_GateRoom
        {
            get { return b_requestActivate_PaintingRoom3_To_GateRoom; }
            set { b_requestActivate_PaintingRoom3_To_GateRoom = value; }
        }
        bool b_requestActivate_PaintingRoom3_To_GateRoom;

        #endregion

        #region PaintingRoom4//hmm

        public bool b_isCollidingWith_PaintingRoom4_To_GateRoom = false;//hmm

        public bool b_RequestActivate_PaintingRoom4_To_GateRoom
        {
            get { return b_requestActivate_GateRoom_To_PaintingRoom4; }
            set { b_requestActivate_GateRoom_To_PaintingRoom4 = value; }
        }
        bool b_requestActivate_PaintingRoom4_To_GateRoom;

        public bool b_isCollidingWith_PaintingRoom4_To_MusicBoxRoom = false;

        public bool b_RequestActivate_PaintingRoom4_To_MusicBoxRoom
        {
            get { return b_requestActivate_PaintingRoom4_To_MusicBoxRoom; }
            set { b_requestActivate_PaintingRoom4_To_MusicBoxRoom = value; }
        }
        bool b_requestActivate_PaintingRoom4_To_MusicBoxRoom;
        
        #endregion

        #region Music Box Room

        public bool b_isCollidingWith_MusicBoxRoom_To_RoomA = false;

        public bool b_RequestActivate_MusicBoxRoom_To_RoomA
        {
            get { return b_requestActivate_MusicBoxRoom_To_RoomA; }
            set { b_requestActivate_MusicBoxRoom_To_RoomA = value; }
        }
        bool b_requestActivate_MusicBoxRoom_To_RoomA;

        #endregion

        #region Room B

        public bool b_isCollidingWith_B_To_Hallway = false;

        public bool b_RequestActivate_BToHall
        {
            get { return b_requestActivate_BToHall; }
            set { b_requestActivate_BToHall = value; }
        }
        bool b_requestActivate_BToHall;

        public bool b_isCollidingWith_B_To_C = false;

        public bool b_RequestActivate_BtoC
        {
            get { return b_requestActivate_BtoC; }
            set { b_requestActivate_BtoC = value; }
        }
        bool b_requestActivate_BtoC;

        public bool b_isCollidingWith_RoomBDoorTrigger = false;

        public bool b_RequestActivate_RoomBDoorTrigger
        {
            get { return b_requestActivate_RoomBDoorTrigger; }
            set { b_requestActivate_RoomBDoorTrigger = value; }
        }
        bool b_requestActivate_RoomBDoorTrigger;

        #endregion

        #region Room C

        public bool b_isCollidingWith_C_To_B = false;

        public bool b_RequestActivate_CToB
        {
            get { return b_requestActivate_CToB; }
            set { b_requestActivate_CToB = value; }
        }
        bool b_requestActivate_CToB;


        #endregion

        #region RoomD

        public bool b_isCollidingWith_D_To_Hallway = false;

        public bool b_RequestActivate_DToHall
        {
            get { return b_requestActivate_DToHall; }
            set { b_requestActivate_DToHall = value; }
        }
        bool b_requestActivate_DToHall;

        bool b_isCollidingwith_D_To_BlockRoom1 = false;

        public bool b_RequestActivate_DToBackRoom1
        {
            get { return b_requestActivate_DToBlockRoom1; }
            set { b_requestActivate_DToBlockRoom1 = value; }
        }
        bool b_requestActivate_DToBlockRoom1;

        public bool b_RequestActivate_RoomD_PlateTrigger_Unlock_BlockRoom1
        {
            get { return b_requestActivate_RoomD_PlateTrigger_Unlock_BlockRoom1; }
            set { b_requestActivate_RoomD_PlateTrigger_Unlock_BlockRoom1 = value; }
        }
        bool b_requestActivate_RoomD_PlateTrigger_Unlock_BlockRoom1;

       // public bool b_IsGateActive = true;

        #endregion

        #region BlockRoom1

        public bool b_isCollidingWith_BlockRoom1_To_RoomD = false;

        public bool b_RequestActivate_BlockRoom1ToRoomD
        {
            get { return b_requestActivate_BlockRoom1ToRoomD; }
            set { b_requestActivate_BlockRoom1ToRoomD = value; }
        }
        bool b_requestActivate_BlockRoom1ToRoomD;

        public bool b_isCollidingWith_BlockRoom1_To_BlockRoom2 = false;

        public bool b_RequestActivate_BlockRoom1_To_BlockRoom2
        {
            get { return b_requestActivate_BlockRoom1ToBlockRoom2; }
            set { b_requestActivate_BlockRoom1ToBlockRoom2 = value; }
        }
        bool b_requestActivate_BlockRoom1ToBlockRoom2;

        #endregion

        #region BlockRoom2

        public bool b_isCollidingWith_BlockRoom2_To_BlockRoom1 = false;

        public bool b_RequestActivate_BlockRoom2_To_BlockRoom1
        {
            get { return b_requestActivate_BlockRoom2_To_BlockRoom1; }
            set { b_requestActivate_BlockRoom2_To_BlockRoom1 = value; }
        }
        bool b_requestActivate_BlockRoom2_To_BlockRoom1;

        public bool b_isCollidingWith_BlockRoom2_To_RoomA = false;

        public bool b_RequestActivate_BlockRoom2_To_RoomA
        {
            get { return b_requestActivate_BlockRoom2ToRoomA; }
            set { b_requestActivate_BlockRoom2ToRoomA = value; }
        }
        bool b_requestActivate_BlockRoom2ToRoomA;

        #endregion

        #region Gate Room

        public bool b_isCollidingWith_GateRoom_To_PaintingRoom4 = false;

        public bool b_RequestActivate_GateRoom_To_PaintingRoom4
        {
            get { return b_requestActivate_GateRoom_To_PaintingRoom4; }
            set { b_requestActivate_GateRoom_To_PaintingRoom4 = value; }
        }
        bool b_requestActivate_GateRoom_To_PaintingRoom4;

        public bool b_isCollidingWith_GateRoom_LeverTrigger = false;

        public bool b_RequestActivate_GateRoom_LeverTrigger
        {
            get { return b_requestActivate_GateRoom_LeverTrigger; }
            set { b_requestActivate_GateRoom_LeverTrigger = value; }
        }
        bool b_requestActivate_GateRoom_LeverTrigger;

        #endregion

        #region Friend Room

        public bool b_isCollidingWith_FriendRoom_To_RoomD = false;

        public bool b_RequestActivate_FriendToD
        {
            get { return b_requestActivate_FriendToD; }
            set { b_requestActivate_FriendToD = value; }
        }
        bool b_requestActivate_FriendToD;

        #endregion

        bool b_isCollidingWith_Ladder = false;
        bool b_isCollidingWith_Stairs = false;
        //these need no request to activate, they just do, unless they require collision with pushable objects (coming soon)


        #endregion

        #region Animation Booleans

        bool b_IsIdleAnimationPlaying;
        bool b_IsRunAnimationPlaying;
        bool b_IsJumpAnimationPlaying;
        bool b_IsClimbAnimationPlaying;

        #endregion

        private Rectangle rec_localBounds;

        public Rectangle BoundingRectangle
        {
            get
            {
                int i_left = (int)Math.Round(v2_Position.X - Mallory.Origin.X) + rec_localBounds.X;
                int i_top = (int)Math.Round(v2_Position.Y - Mallory.Origin.Y) + rec_localBounds.Y;

                return new Rectangle(i_left, i_top, rec_localBounds.Width, rec_localBounds.Height);
            }
        }

        public Rectangle rec_Bounds;
        #endregion

        public PlayerEntity()
        {
            //initialize what needs to be initialized here.

            //Spawn(Vector2.Zero);//this will not happen here. this will happen outside the player code from the actual collision map.
        }

        public void LoadContent(ContentManager content)
        {
            v2_position = Vector2.Zero;
            b_isAlive = true;

            t2d_SpritePic = content.Load<Texture2D>("GameplayScreenContent/Sprites/PlayerOne");
            t2d_DarknessOverlay = content.Load<Texture2D>("GameplayScreenContent/Overlays/DarknessOverlay");


            Mallory = new Animation.SpriteAnimation(content.Load<Texture2D>("GameplayScreenContent/Sprites/Animation"), 8, 5);
            Animation.AnimationClass animation = new Animation.AnimationClass(Color.White, 1.0f, SpriteEffects.None);

            Mallory.AddAnimation("Idle", 1, 1, animation.Copy());
            Mallory.AddAnimation("Run", 2, 8, animation.Copy());
            Mallory.AddAnimation("Push", 3, 8, animation.Copy());
            Mallory.AddAnimation("Climb", 4, 6, animation.Copy());
            Mallory.AddAnimation("Jump", 5, 5, animation.Copy());
            Mallory.FramesPerSecond = 8;

            v2_DarknessOrigin = new Vector2((t2d_DarknessOverlay.Width / 2), (t2d_DarknessOverlay.Height / 2));

            se_Death = content.Load<SoundEffect>("Audio/SoundEffects/DeathCry");
            se_DoorOpenOne = content.Load<SoundEffect>("Audio/SoundEffects/DoorOne");
            se_DoorOpenTwo = content.Load<SoundEffect>("Audio/SoundEffects/DoorTwo");
            se_LampOn = content.Load<SoundEffect>("Audio/SoundEffects/LampOn");
            se_LampOff = content.Load<SoundEffect>("Audio/SoundEffects/CannotSummon");
            se_Latch = content.Load<SoundEffect>("Audio/SoundEffects/Latch");
            se_WeightSwitch = content.Load<SoundEffect>("Audio/SoundEffects/BigDoor");
            se_LockedDoor = content.Load<SoundEffect>("Audio/SoundEffects/LockedDoor");
            se_DespawnCry = content.Load<SoundEffect>("Audio/SoundEffects/DespawnCry");
            se_SpawnReadyCry = content.Load<SoundEffect>("Audio/SoundEffects/SpawnReadyCry");
            se_CannotSummon = content.Load<SoundEffect>("Audio/SoundEffects/CannotSummon2");

            song_HeartBeatFast = content.Load<Song>("Audio/SoundEffects/FastHeartBeat");
            song_HeartBeatModerate = content.Load<Song>("Audio/SoundEffects/StandardHeartBeat");
            song_AmbiantBGM = content.Load<Song>("Audio/SoundEffects/AmbiantOne");

            sei_Death = se_Death.CreateInstance();
            sei_DoorOpenOne = se_DoorOpenOne.CreateInstance();
            sei_DoorOpenTwo = se_DoorOpenTwo.CreateInstance();
            sei_LampOn = se_LampOn.CreateInstance();
            sei_LampOff = se_LampOff.CreateInstance();
            sei_Latch = se_Latch.CreateInstance();
            sei_WeightSwitch = se_WeightSwitch.CreateInstance();
            sei_LockedDoor = se_LockedDoor.CreateInstance();
            sei_SpawnReadyCry = se_SpawnReadyCry.CreateInstance();
            sei_DespawnCry = se_SpawnReadyCry.CreateInstance();
            sei_CannotSummon = se_CannotSummon.CreateInstance();

            MediaPlayer.IsRepeating = true;

            //calculate bounds within the texture.
            int Width = (int)(t2d_SpritePic.Width - 12);
            int Left = 6;
            int Height = (int)(t2d_SpritePic.Height - 17);
            int Top = 0;

            rec_localBounds = new Rectangle(Left, Top, Width, Height);

            //Player Vars
            f_healthState = 100.0f;
            b_isHit = false;
            b_HeartBeatFast = false;
            b_HeartBeatNormal = false;
            b_Ambiance = true;

            //Friends Logic
            b_friendTimeOut = false;
            b_RequestAbilityOneActivate = false;
            b_RequestFollow = true;
            b_RequestStay = false;
            b_RequestSummon = false;
        }

        /// <summary>
        /// This spawn command will completely reset the character values 
        /// </summary>
        /// <param name="sPosition"> The position at which to spawn</param>
        public void Spawn(Vector2 sPosition)
        {
            v2_position.X = (sPosition.X * CollidingTile.i_TileWidth) + Mallory.Origin.X;
            v2_position.Y = (sPosition.Y * CollidingTile.i_TileHeight) + 20.0f;

            v2_Velocity = Vector2.Zero;
            b_isAlive = true;

            //Mallory.Animation = "Idle";
            //Mallory.IsLooping = true;
            Mallory.Position = v2_Position;

            //reset boolean values for door activation
            //b_RequestActivate_First_Door1 = false;
        }

        //will make another spawn command
        //that will move the player to that position without
        //resetting anything.
        //maybe something like CenterOnTile(tilePosition)
        public void Update(GameTime gameTime, InputHandler input, TileMap_Colliding collisionMap, State gameScreenState)
        {

            if (b_hasKnifeKey && b_isCollidingWith_BedTile)
            {
                b_CanEndGame = true;
            }


            #region Health Checks
            //Health Check
            if (f_healthState <= 0.0f)
            {
                //HealthState = Dead
                MediaPlayer.Stop();
                b_isAlive = false;
                sei_Death.Play();
            }
            else if ((f_healthState >= 1.0f) && (f_healthState < 25.0f))
            {
                if (!b_HeartBeatFast)
                {
                    MediaPlayer.Stop();
                    b_HeartBeatFast = true;
                    b_Ambiance = false;
                    b_HeartBeatNormal = false;
                }

                //HealthState Bad
                if (MediaPlayer.State != MediaState.Playing)
                {

                    MediaPlayer.Play(song_HeartBeatFast);
                }
            }
            else if ((f_healthState >= 25.0f) && (f_healthState < 60.0f))
            {
                if (!b_HeartBeatNormal)
                {
                    MediaPlayer.Stop();
                    b_HeartBeatNormal = true;
                    b_Ambiance = false;
                    b_HeartBeatFast = false;
                }
                //HealthState Startled
                if (MediaPlayer.State != MediaState.Playing)
                {
                    MediaPlayer.Play(song_HeartBeatModerate);
                }
            }
            else
            {
                if (f_healthState >= 60.0f)
                {
                    if (!b_Ambiance)
                    {
                        MediaPlayer.Stop();
                        b_Ambiance = true;
                        b_HeartBeatNormal = false;
                        b_HeartBeatFast = false;
                    }
                }

                if (MediaPlayer.State != MediaState.Playing)
                {
                    MediaPlayer.Stop();
                    MediaPlayer.Play(song_AmbiantBGM);
                }
            }

            //---
            #endregion

            if (b_requestActivate_RoomD_PlateTrigger_Unlock_BlockRoom1)
            {
                if (sei_Latch.State != SoundState.Playing && !b_hasSoundPlayed)
                {
                    sei_WeightSwitch.Play();
                    b_hasSoundPlayed = true;
                }
            }

            if (b_requestActivate_GateTrigger_BlockRoom2ToRoomA)
            {
                if (sei_Latch.State != SoundState.Playing && !b_hasSound2Played)
                {
                    sei_WeightSwitch.Play();
                    b_hasSound2Played = true;
                }
            }


            if (b_requestActivate_GateTrigger_BlockRoom2ToRoomA)
                b_isRoomAGateActive = false;
            else b_isRoomAGateActive = true;

            

            #region Friend Update Logic
            //-----
            if (b_HasLampKey)
            {
                if (b_RequestSummon)
                {
                    f_SummonTimer++;
                }
                else if (b_friendTimeOut)
                {
                    f_SummonTimer--;
                }

                if ((f_SummonTimer >= f_MaxSummonTimer) && (!b_friendTimeOut))
                {
                    sei_DespawnCry.Play();
                    b_RequestSummon = false;
                    b_RequestDeSummon = true;
                    b_RequestAbilityOneActivate = false;
                    b_RequestAbilityOneStop = true;
                    b_friendTimeOut = true;
                }
                else if ((f_SummonTimer <= 0.0f) && (b_friendTimeOut))
                {
                    sei_SpawnReadyCry.Play();
                    b_friendTimeOut = false;
                }
            }
            //-----
            #endregion

            //quick change for pause menu boolean
            if (gameScreenState == State.Active)
            {
                b_RequestPauseMenuOpen = false;
            }

            #region If Alive!
            //check player values
            if (b_IsAlive)
            {
                if (!b_IsIdleAnimationPlaying)
                {
                    Mallory.Animation = "Idle";
                    b_IsIdleAnimationPlaying = true;
                    Mallory.IsLooping = true;
                }

                ApplyInput(input);
                ApplyPhysics(gameTime, collisionMap, input);

                //clear input
                f_movementX = 0.0f;
                b_isJumping = false;

                Mallory.Position = v2_Position;
                Mallory.Update(gameTime);
            }
            #endregion
        }

        private void ApplyInput(InputHandler input)
        {
            b_requestActivate_StartToHall = false;

            //PushDirection = MoveDirection.None;

            if (Math.Abs(f_movementX) < 0.5f)
            {
                //spriteEffect = SpriteEffects.None;
                f_movementX = 0.0f;

            }

            if ((input.GetKBState(Keys.Left)))// || input.GetGPState(Buttons.DPadLeft))
            {
                //move left.
                if (!b_IsRunAnimationPlaying)
                {
                    Mallory.Animation = "Run";
                    b_IsRunAnimationPlaying = true;
                }
                spriteEffect = SpriteEffects.FlipHorizontally;
                f_movementX = -1.0f;
                PushDirection = MoveDirection.left;


                //change animation
            }

            if ((input.GetKBState(Keys.Right)))// || input.GetGPState(Buttons.DPadRight))
            {
                if (!b_IsRunAnimationPlaying)
                {
                    Mallory.Animation = "Run";
                    b_IsRunAnimationPlaying = true;
                }
                spriteEffect = SpriteEffects.None;
                f_movementX = 1.0f;
                PushDirection = MoveDirection.right;


            }

            if ((input.GetKBStateReleased(Keys.Left) && input.GetKBStateReleased(Keys.Right)) &&
               (input.GetGPStateReleased(Buttons.DPadLeft) && input.GetGPStateReleased(Buttons.DPadRight)))
            {
                b_IsRunAnimationPlaying = false;
                if (b_IsIdleAnimationPlaying)
                    b_IsIdleAnimationPlaying = false;

            }

            if ((input.GetKBState(Keys.Space)) || (input.GetGPState(Buttons.A)))
            {
                b_isJumping = true;
                Mallory.Animation = "Jump";
                b_IsJumpAnimationPlaying = true;
                b_IsRunAnimationPlaying = false;
                b_IsIdleAnimationPlaying = false;
            }

            #region Player to Friend Commands

            if ((input.GetKBStateSingle(Keys.P)) || (input.GetGPStateSingle(Buttons.B)))
            {//the value will change based on the inventory menu.
                if (b_HasMusicBox)//you can summon.
                {
                    if (b_HasLampKey)//one for each based on which is equipped.
                    {
                        if (!b_friendTimeOut)
                        {
                            //---Summoning / Desummoning Requests
                            if (!b_RequestSummon)//If not summoned, summon.
                            {
                                sei_SpawnReadyCry.Play();
                                f_SummonTimer = 0.0f;
                                b_RequestSummon = true;
                                b_RequestDeSummon = false;
                            }
                            else if (b_RequestSummon)//Else, if summoned, then de-summon.
                            {
                                sei_DespawnCry.Play();
                                f_SummonTimer = 0.0f;
                                b_RequestDeSummon = true;
                                b_RequestSummon = false;
                                b_RequestAbilityOneActivate = false;
                            }
                        }
                        else
                        {
                            if (sei_CannotSummon.State != SoundState.Playing)
                                sei_CannotSummon.Play();

                            //Timed out, no summon available.
                        }
                    }
                    else
                    {
                        if (sei_CannotSummon.State != SoundState.Playing)
                            sei_CannotSummon.Play();
                    }
                }
                else
                {
                    if (sei_CannotSummon.State != SoundState.Playing)
                        sei_CannotSummon.Play();
                }

            }

            if (b_RequestSummon)
            {
                //---Stay / Follow Requests
                if ((input.GetKBStateSingle(Keys.S) || (input.GetGPStateSingle(Buttons.RightShoulder))) && (!b_RequestStay))
                {
                    //Stay here.
                    b_RequestStay = true;
                    b_RequestFollow = false;
                    v2_stayHerePosition = v2_position;
                }
                else if ((input.GetKBStateSingle(Keys.S) || (input.GetGPStateSingle(Buttons.RightShoulder))) && (b_RequestStay))
                {
                    //Else, follow me.
                    b_RequestFollow = true;
                    b_RequestStay = false;
                }

                //---Ability Requests
                if ((input.GetKBStateSingle(Keys.A) || (input.GetGPStateSingle(Buttons.LeftShoulder))) && (!b_RequestAbilityOneActivate))
                {
                    //If ability one is not on, please activate.
                    sei_LampOn.Play();
                    b_RequestAbilityOneActivate = true;
                    b_RequestAbilityOneStop = false;
                }
                else if ((input.GetKBStateSingle(Keys.A) || (input.GetGPStateSingle(Buttons.LeftShoulder))) && (b_RequestAbilityOneActivate))
                {
                    //Please stop using your ability.
                    sei_LampOff.Play();
                    b_RequestAbilityOneStop = true;
                    b_RequestAbilityOneActivate = false;
                }
            }

            #endregion

            #region Player to Map Commands

            //testing door logic without doors.
            if (input.GetKBStateSingle(Keys.I) || (input.GetGPStateSingle(Buttons.X)))
            {
                #region Start to Hall
                if (b_isCollidingWith_StartToHallway)//this'll check ALL doors. another long but necessary piece of code.
                {// If I had more time to play around with it, it'd be much more elegant.

                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_StartToHall)
                        b_requestActivate_StartToHall = true;
                }
                #endregion

                #region Hall To Start

                if (b_isCollidingWith_HallwayToStart)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }
                    
                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_HallToStart)
                        b_requestActivate_HallToStart = true;
                }
                #endregion

                #region Hall to A
                if (b_isCollidingWith_Hallway_to_A)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_HallToA)
                        b_requestActivate_HallToA = true;
                }
                #endregion

                #region A To Hall
                if (b_isCollidingWith_A_To_Hallway)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_AToHall)
                        b_requestActivate_AToHall = true;
                }
                #endregion

                #region A to Paint Room1
                if (b_isCollidingWith_A_To_PaintRoom1)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_AToPaintRm1)
                        b_requestActivate_AToPaintRm1 = true;
                }
                #endregion

                #region Paint Room 1 To A
                if (b_isCollidingWith_PaintingRoom1_To_RoomA)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom1_To_RoomA)
                        b_requestActivate_PaintingRoom1_To_RoomA = true;
                }
                #endregion

                #region Paint Room 1 To Paint Room 2
                if (b_isCollidingWith_PaintingRoom1_To_PaintingRoom2)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom1_To_PaintingRoom2)
                        b_requestActivate_PaintingRoom1_To_PaintingRoom2 = true;
                }
                #endregion

                #region Paint Room2 To Paint Room 1
                if (b_isCollidingWith_PaintingRoom2_To_PaintingRoom1)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom2_To_PaintingRoom1)
                        b_requestActivate_PaintingRoom2_To_PaintingRoom1 = true;
                }
                #endregion

                #region Paint Room 2 To Paint Room 3

                if (b_isCollidingWith_PaintingRoom2_To_PaintingRoom3)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom2_to_PaintingRoom3)
                        b_requestActivate_PaintingRoom2_to_PaintingRoom3 = true;
                }
                #endregion

                #region Paint Room 3 To Paint Room 1
                if (b_isCollidingWith_PaintingRoom3_To_PaintingRoom1)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom3_To_PaintingRoom1)
                        b_requestActivate_PaintingRoom3_To_PaintingRoom1 = true;
                }
                #endregion

                #region Paint Room 3 To Gate Room

                if (b_isCollidingWith_PaintingRoom3_To_GateRoom)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom3_To_GateRoom)
                        b_requestActivate_PaintingRoom3_To_GateRoom = true;
                }
                #endregion

                #region Gate Room To Paint room 4
                if (b_isCollidingWith_GateRoom_To_PaintingRoom4)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_GateRoom_To_PaintingRoom4)
                        b_requestActivate_GateRoom_To_PaintingRoom4 = true;
                }
                #endregion

                #region Painting Room 4 to Gate Room
                if (b_isCollidingWith_PaintingRoom4_To_GateRoom)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom4_To_GateRoom)
                        b_requestActivate_PaintingRoom4_To_GateRoom = true;
                }

                #endregion

                #region Painting Room 4 To Music Box Room

                if (b_isCollidingWith_PaintingRoom4_To_MusicBoxRoom)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_PaintingRoom4_To_MusicBoxRoom)
                        b_requestActivate_PaintingRoom4_To_MusicBoxRoom = true;
                }

                #endregion

                #region Music Box Room to Room A

                if (b_isCollidingWith_MusicBoxRoom_To_RoomA)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_MusicBoxRoom_To_RoomA)
                        b_requestActivate_MusicBoxRoom_To_RoomA = true;
                }

                #endregion

                #region Hall To B
                if (b_isCollidingWith_Hallway_To_B)
                {
                    if (b_requestActivate_GateRoom_LeverTrigger)
                    {
                        if (b_RequestSummon)
                        {
                            b_RequestAbilityOneActivate = false;
                            b_RequestAbilityOneStop = true;
                            b_RequestFollow = true;
                            b_RequestStay = false;
                            b_RequestSummon = false;
                            b_RequestDeSummon = true;
                        }
                        sei_DoorOpenOne.Play();
                    }
                    else
                    {
                        sei_LockedDoor.Play();
                    }

                    if (!b_requestActivate_HallToB)
                        b_requestActivate_HallToB = true;
                }
                #endregion

                #region B to Hall
                if (b_isCollidingWith_B_To_Hallway)
                {
                    if (b_requestActivate_RoomBDoorTrigger)
                    {
                        if (b_RequestSummon)
                        {
                            b_RequestAbilityOneActivate = false;
                            b_RequestAbilityOneStop = true;
                            b_RequestFollow = true;
                            b_RequestStay = false;
                            b_RequestSummon = false;
                            b_RequestDeSummon = true;
                        }

                        sei_DoorOpenOne.Play();
                    }
                    else
                    {
                        sei_LockedDoor.Play();
                    }
                    if (!b_requestActivate_BToHall)
                        b_requestActivate_BToHall = true;
                }
                #endregion

                #region B to C // recip
                if (b_isCollidingWith_B_To_C)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_BtoC)
                        b_requestActivate_BtoC = true;
                }
                #endregion

                #region C to B // recip

                if (b_isCollidingWith_C_To_B)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_CToB)
                        b_requestActivate_CToB = true;
                }
                #endregion

                #region Hall To D
                if (b_isCollidingWith_Hallway_To_D)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_HallToD)
                        b_requestActivate_HallToD = true;
                }
                #endregion

                #region D to Hall

                if (b_isCollidingWith_D_To_Hallway)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }
                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_DToHall)
                        b_requestActivate_DToHall = true;
                }
                #endregion

                #region D to Block Room 1
                if (b_isCollidingwith_D_To_BlockRoom1)
                {
                    if (b_requestActivate_RoomD_PlateTrigger_Unlock_BlockRoom1)
                    {
                        if (b_RequestSummon)
                        {
                            b_RequestAbilityOneActivate = false;
                            b_RequestAbilityOneStop = true;
                            b_RequestFollow = true;
                            b_RequestStay = false;
                            b_RequestSummon = false;
                            b_RequestDeSummon = true;
                        }


                        sei_DoorOpenOne.Play();
                    }
                    else
                    {
                        sei_LockedDoor.Play();
                    }
                    if (!b_requestActivate_DToBlockRoom1)
                        b_requestActivate_DToBlockRoom1 = true;
                }
                #endregion

                #region Block Room 1 To D

                if (b_isCollidingWith_BlockRoom1_To_RoomD)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_BlockRoom1ToRoomD)
                        b_requestActivate_BlockRoom1ToRoomD = true;
                }
                #endregion

                #region Block Room 2 to Block Room 2

                if (b_isCollidingWith_BlockRoom1_To_BlockRoom2)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_BlockRoom1ToBlockRoom2)
                        b_requestActivate_BlockRoom1ToBlockRoom2 = true;
                }
                #endregion

                #region BLock Room 1 To Block Room 1

                if (b_isCollidingWith_BlockRoom2_To_BlockRoom1)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_BlockRoom2_To_BlockRoom1)
                        b_requestActivate_BlockRoom2_To_BlockRoom1 = true;
                }
                #endregion

                #region Block Room 2 to A
                if (b_isCollidingWith_BlockRoom2_To_RoomA)
                {
                    if (b_RequestSummon)
                    {
                        b_RequestAbilityOneActivate = false;
                        b_RequestAbilityOneStop = true;
                        b_RequestFollow = true;
                        b_RequestStay = false;
                        b_RequestSummon = false;
                        b_RequestDeSummon = true;
                    }

                    sei_DoorOpenOne.Play();
                    if (!b_requestActivate_BlockRoom2ToRoomA)
                        b_requestActivate_BlockRoom2ToRoomA = true;
                }
                #endregion



                if (b_isCollidingWith_GateRoom_LeverTrigger)
                {
                    //TRIGGER
                    if (sei_Latch.State != SoundState.Playing)
                    {
                        sei_Latch.Play();
                    }

                    if (!b_requestActivate_GateRoom_LeverTrigger)
                        b_requestActivate_GateRoom_LeverTrigger = true;
                    else b_requestActivate_GateRoom_LeverTrigger = false;
                }

               
            }

            #endregion

            #region GameScreen Control Commands

            if (input.GetKBStateSingle(Keys.O))
            {

            }

            #endregion

        }

        private void ApplyPhysics(GameTime gameTime, TileMap_Colliding collisionMap, InputHandler input)
        {
            float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;


            Vector2 v2_previousPosition = v2_Position;

            v2_velocity.X += f_movementX * Physics.MoveAcceleration * elapsed;

            if (!b_isCollidingWith_Ladder && !b_isCollidingWith_Stairs)
            {
                v2_velocity.Y = MathHelper.Clamp(v2_velocity.Y + Physics.GravityAcceleration * elapsed, -Physics.MaxFallSpeed, Physics.MaxFallSpeed);
            }

            //do jump physics.
            v2_velocity.Y = DoJump(v2_velocity.Y, gameTime);

            if (b_IsOnGround)
                v2_velocity.X *= Physics.GroundDragFactor;
            else
                v2_velocity.X *= Physics.AirDragFactor;

            //prevent the player from running faster than top speed.
            v2_velocity.X = MathHelper.Clamp(v2_velocity.X, -Physics.MaxMoveSpeed, Physics.MaxMoveSpeed);

            //apply velocity.
            v2_Position += v2_velocity * elapsed;
            v2_Position = new Vector2((float)Math.Round(v2_Position.X), (float)Math.Round(v2_Position.Y));

            //Handle Collisions.
            HandleCollisions(collisionMap, input);


            //If collisions have stopped us from moving, reset the velocity to 0
            if (v2_Position.X == v2_previousPosition.X)
                v2_velocity.X = 0;
            if (v2_Position.Y == v2_previousPosition.Y)
                v2_velocity.Y = 0;

        }

        private float DoJump(float f_velocityY, GameTime gameTime)
        {
            if (b_isJumping)
            {
                //begin or continue a jump
                if ((!b_wasJumping && b_IsOnGround) || f_jumpTime > 0.0f)
                {
                    f_jumpTime += (float)gameTime.ElapsedGameTime.TotalSeconds;
                }

                //if we are in the ascent of a jump...
                if (0.0f < f_jumpTime && f_jumpTime <= Physics.MaxJumpTime)
                {
                    //fully override vertical velocity
                    f_velocityY = Physics.JumpLaunchVelocity * (1.0f - (float)Math.Pow(f_jumpTime / Physics.MaxJumpTime, Physics.JumpControlPower));
                }
                else
                {
                    //reached the apex of the jump.
                    f_jumpTime = 0.0f;
                }
            }
            else
            {
                //continues not jumping or cancels a jump.
                f_jumpTime = 0.0f;
            }
            b_wasJumping = b_isJumping;

            return f_velocityY;
        }

        private void HandleCollisions(TileMap_Colliding collisionMap, InputHandler input)
        {
            #region Reset Collision Variables for Doors // May make a small function to hide this away.
            b_isCollidingWith_StartToHallway = false;
            b_isCollidingWith_BedTile = false;

            b_isCollidingWith_HallwayToStart = false;
            b_isCollidingWith_Hallway_to_A = false;
            b_isCollidingWith_Hallway_To_D = false;
            b_isCollidingWith_Hallway_To_B = false;

            b_isCollidingWith_A_To_Hallway = false;
            b_isCollidingWith_A_To_PaintRoom1 = false;

            b_isCollidingWith_PaintingRoom1_To_RoomA = false;
            b_isCollidingWith_PaintingRoom1_To_PaintingRoom2 = false;

            b_isCollidingWith_PaintingRoom2_To_PaintingRoom1 = false;
            b_isCollidingWith_PaintingRoom2_To_PaintingRoom3 = false;

            b_isCollidingWith_PaintingRoom3_To_GateRoom = false;
            b_isCollidingWith_PaintingRoom3_To_PaintingRoom1 = false;

            b_isCollidingWith_GateRoom_To_PaintingRoom4 = false;

            b_isCollidingWith_PaintingRoom4_To_GateRoom = false;
            b_isCollidingWith_PaintingRoom4_To_MusicBoxRoom = false;

            b_isCollidingWith_MusicBoxRoom_To_RoomA = false;

            b_isCollidingWith_B_To_Hallway = false;
            b_isCollidingWith_B_To_C = false;
            b_isCollidingWith_RoomBDoorTrigger = false;

            b_isCollidingWith_C_To_B = false;

            b_isCollidingWith_D_To_Hallway = false;
            b_isCollidingwith_D_To_BlockRoom1 = false;

            b_isCollidingWith_BlockRoom1_To_RoomD = false;
            b_isCollidingWith_BlockRoom1_To_BlockRoom2 = false;

            b_isCollidingWith_BlockRoom2_To_BlockRoom1 = false;
            b_isCollidingWith_BlockRoom2_To_RoomA = false;

            
            b_isCollidingWith_GateRoom_LeverTrigger = false;

            b_isCollidingWith_FriendRoom_To_RoomD = false;

            b_isCollidingWith_A_Trigger_To_Gate = false;

            //b_isCollidingWith_First_PlateTrigger1 = false;
            //b_iscolliding_with_event_1_tile = false;
            b_isCollidingWith_Ladder = false;
            b_isCollidingWith_Stairs = false;

            #endregion

            //Get the player's bounding rectangle and find the neighboring tiles.
            rec_Bounds = BoundingRectangle;

            int i_leftTile = (int)Math.Floor((float)rec_Bounds.Left / CollidingTile.i_TileWidth);
            int i_rightTile = (int)Math.Ceiling(((float)rec_Bounds.Right / CollidingTile.i_TileWidth)) - 1;
            int i_topTile = (int)Math.Floor((float)rec_Bounds.Top / CollidingTile.i_TileHeight);
            int i_bottomTile = (int)Math.Ceiling(((float)rec_Bounds.Bottom / CollidingTile.i_TileHeight)) - 1;

            //Reset Flag to search for ground collision.
            b_isOnGround = false;

            //For Each Potentially Colliding Tile...
            for (int y = i_topTile; y <= i_bottomTile; ++y)
            {
                for (int x = i_leftTile; x <= i_rightTile; ++x)
                {
                    TTPCollision = collisionMap.GetCollision(x, y);

                    #region If the Tile is a collision Tile...

                    //if it's collidable
                    if (TTPCollision == TileCollision.Impassable || TTPCollision == TileCollision.Platform)//all collision type checks will happen here.
                    {
                        Rectangle rec_tileBounds = collisionMap.GetBounds(x, y);

                        Vector2 v2_depth = RectangleExtensions.GetIntersectionDepth(rec_Bounds, rec_tileBounds);

                        if (v2_depth != Vector2.Zero)//if actually colliding
                        {
                            //get the absolute value of the depth of intersection
                            float f_absDepthX = Math.Abs(v2_depth.X);
                            float f_absDepthY = Math.Abs(v2_depth.Y);

                            //resolve along the shallow axis.
                            if (f_absDepthY < f_absDepthX || TTPCollision == TileCollision.Platform)
                            {
                                //if we crossed the top of a platform / tile, we are on the ground.
                                if (f_previousBottom <= rec_tileBounds.Top)
                                    b_isOnGround = true;

                                //Ignore platforms, unless we're on the ground.
                                if ((TTPCollision == TileCollision.Impassable || b_IsOnGround))
                                {
                                    //resolve the collision along the Y axis.
                                    v2_Position = new Vector2(v2_Position.X, v2_Position.Y + v2_depth.Y);

                                    //perform further collisions with the new bounds.
                                    rec_Bounds = BoundingRectangle;
                                }

                            }

                            else if (TTPCollision == TileCollision.Impassable)//Ignore platforms completely
                            {
                                //resolve collision along the X axis.
                                v2_Position = new Vector2(v2_Position.X + v2_depth.X, v2_Position.Y);

                                //perform further collisions with the new bounds
                                rec_Bounds = BoundingRectangle;
                            }

                        }
                    }

                    #endregion

                    #region OTher Tile Collision Types

                    else if (TTPCollision == TileCollision.Passable)
                    {
                        b_isOnGround = false;
                    }

                    else if (TTPCollision == TileCollision.BedTile)
                    {
                        b_isCollidingWith_BedTile = true;
                    }

                    else if (TTPCollision == TileCollision.Ladder)
                    {

                        b_isCollidingWith_Ladder = true;
                        if (input.GetKBState(Keys.Up) || input.GetGPState(Buttons.DPadUp))
                        {
                            Mallory.Animation = "Climb";
                            b_IsIdleAnimationPlaying = false;
                            b_IsRunAnimationPlaying = false;
                            b_IsJumpAnimationPlaying = false;
                            b_IsClimbAnimationPlaying = true;

                            v2_position.Y -= 2.0f;

                        }
                        if (input.GetKBState(Keys.Down) || input.GetGPState(Buttons.DPadDown))
                        {
                            Mallory.Animation = "Climb";
                            b_IsIdleAnimationPlaying = false;
                            b_IsRunAnimationPlaying = false;
                            b_IsJumpAnimationPlaying = false;
                            b_IsClimbAnimationPlaying = true;

                            v2_position.Y += 2.0f;
                        }

                        b_isOnGround = true;
                        v2_position = new Vector2(v2_Position.X, v2_Position.Y);
                        rec_Bounds = BoundingRectangle;


                    }

                    else if (TTPCollision == TileCollision.DiagonalRightStairs)
                    {
                        b_isCollidingWith_Stairs = true;
                        if (input.GetKBState(Keys.Right) || input.GetGPState(Buttons.DPadRight))
                        {
                            v2_position.Y -= 3.0f;
                        }
                        else if (input.GetKBState(Keys.Left) || input.GetGPState(Buttons.DPadLeft))
                        {
                            v2_position.Y += 3.0f;
                        }

                        b_isOnGround = true;
                        v2_position = new Vector2(v2_Position.X, v2_Position.Y);
                        rec_Bounds = BoundingRectangle;

                    }
                    else if (TTPCollision == TileCollision.DiagonalLeftStairs)
                    {
                        b_isCollidingWith_Stairs = true;
                        if (input.GetKBState(Keys.Right) || input.GetGPState(Buttons.DPadRight))
                        {
                            v2_position.Y += 3.0f;
                        }
                        else if (input.GetKBState(Keys.Left) || input.GetGPState(Buttons.DPadLeft))
                        {
                            v2_position.Y -= 3.0f;
                        }

                        b_isOnGround = true;
                        v2_position = new Vector2(v2_Position.X, v2_Position.Y);
                        rec_Bounds = BoundingRectangle;

                    }

                    #region Starting Room
                    else if (TTPCollision == TileCollision.StartingRoom_To_Hallway)
                    {
                        b_isCollidingWith_StartToHallway = true;
                    }
                    #endregion

                    #region Hallway

                    else if (TTPCollision == TileCollision.Hallway_To_StartingRoom)
                    {
                        b_isCollidingWith_HallwayToStart = true;
                    }

                    else if (TTPCollision == TileCollision.Hallway_To_RoomA)
                    {
                        b_isCollidingWith_Hallway_to_A = true;
                    }

                    else if (TTPCollision == TileCollision.Hallway_To_RoomB)
                    {
                        b_isCollidingWith_Hallway_To_B = true;
                    }

                    else if (TTPCollision == TileCollision.Hallway_To_RoomD)
                    {
                        b_isCollidingWith_Hallway_To_D = true;
                    }

                    #endregion

                    #region Room A

                    else if (TTPCollision == TileCollision.RoomA_To_Hallway)
                    {
                        b_isCollidingWith_A_To_Hallway = true;
                    }

                    else if (TTPCollision == TileCollision.RoomA_To_PaintingRoom1)
                    {
                        b_isCollidingWith_A_To_PaintRoom1 = true;
                    }

                    #endregion

                    #region Room B

                    else if (TTPCollision == TileCollision.RoomB_To_Hallway)
                    {
                        b_isCollidingWith_B_To_Hallway = true;
                    }

                    else if (TTPCollision == TileCollision.RoomB_To_RoomC)
                    {
                        b_isCollidingWith_B_To_C = true;
                    }

                    else if (TTPCollision == TileCollision.RoomB_DoorTrigger)
                    {
                        b_isCollidingWith_RoomBDoorTrigger = true;
                        b_requestActivate_RoomBDoorTrigger = true;
                    }

                    #endregion

                    #region Room C
                    else if (TTPCollision == TileCollision.RoomC_To_RoomB)
                    {
                        b_isCollidingWith_C_To_B = true;
                    }


                    #endregion

                    #region Room D

                    else if (TTPCollision == TileCollision.RoomD_To_Hallway)
                    {
                        b_isCollidingWith_D_To_Hallway = true;
                    }

                    else if (TTPCollision == TileCollision.RoomD_To_BlockRoom1)
                    {

                        b_isCollidingwith_D_To_BlockRoom1 = true;
                    }

                    #endregion

                    #region BlockRoom1

                    else if (TTPCollision == TileCollision.BlockRoom1_To_RoomD)
                    {
                        b_isCollidingWith_BlockRoom1_To_RoomD = true;
                    }

                    else if (TTPCollision == TileCollision.BlockRoom1_To_BlockRoom2)
                    {
                        b_isCollidingWith_BlockRoom1_To_BlockRoom2 = true;
                    }

                    #endregion

                    #region BlockRoom2

                    else if (TTPCollision == TileCollision.BlockRoom2_To_BlockRoom1)
                    {
                        b_isCollidingWith_BlockRoom2_To_BlockRoom1 = true;
                    }
                    else if (TTPCollision == TileCollision.BlockRoom2_To_RoomA)
                    {
                        b_isCollidingWith_BlockRoom2_To_RoomA = true;
                    }

                    #endregion

                    #region PaintingRoom1

                    else if (TTPCollision == TileCollision.PaintingRoom1_To_RoomA)
                    {
                        b_isCollidingWith_PaintingRoom1_To_RoomA = true;
                    }

                    else if (TTPCollision == TileCollision.PaintingRoom1_To_PaintingRoom2)
                    {
                        b_isCollidingWith_PaintingRoom1_To_PaintingRoom2 = true;
                    }

                    #endregion

                    #region PaintingRoom2
                    else if (TTPCollision == TileCollision.PaintingRoom2_To_PaintingRoom1)
                    {
                        b_isCollidingWith_PaintingRoom2_To_PaintingRoom1 = true;
                    }

                    else if (TTPCollision == TileCollision.PaintingRoom2_To_PaintingRoom3)
                    {
                        b_isCollidingWith_PaintingRoom2_To_PaintingRoom3 = true;
                    }

                    #endregion

                    #region PaintingRoom3

                    else if (TTPCollision == TileCollision.PaintingRoom3_To_PaintingRoom1)
                    {
                        b_isCollidingWith_PaintingRoom3_To_PaintingRoom1 = true;
                    }

                    else if (TTPCollision == TileCollision.PaintingRoom3_To_GateRoom)
                    {
                        b_isCollidingWith_PaintingRoom3_To_GateRoom = true;
                    }
                    #endregion

                    #region PaintingRoom4

                    else if (TTPCollision == TileCollision.PaintingRoom4_To_GateRoom)
                    {
                        b_isCollidingWith_PaintingRoom4_To_GateRoom = true;
                    }

                    else if (TTPCollision == TileCollision.PaintingRoom4_To_MusicBoxRoom)
                    {
                        b_isCollidingWith_PaintingRoom4_To_MusicBoxRoom = true;
                    }

                    #endregion

                    #region Music Box Room

                    else if (TTPCollision == TileCollision.MusicBoxRoom_To_RoomA)
                    {
                        b_isCollidingWith_MusicBoxRoom_To_RoomA = true;
                    }

                    #endregion

                    #region GateRoom

                    else if (TTPCollision == TileCollision.GateRoom_To_PaintingRoom4)
                    {
                        b_isCollidingWith_GateRoom_To_PaintingRoom4 = true;
                    }

                    else if (TTPCollision == TileCollision.GateRoom_LeverTrigger)
                    {
                        b_isCollidingWith_GateRoom_LeverTrigger = true;
                    }

                    #endregion

                    #region Friend Room
                    else if (TTPCollision == TileCollision.FriendRoom_To_RoomD)
                    {
                        b_isCollidingWith_FriendRoom_To_RoomD = true;
                    }

                    #endregion

                    #endregion

                }
            }

            //set velocity to zero if on the ground.
            if (b_IsOnGround)
                v2_velocity.Y = 0.0f;

            //save the new bounds bottom
            f_previousBottom = rec_Bounds.Bottom;

        }

        public void Draw(SpriteBatch spriteBatch)
        {
            //If alive.
            if (!b_isHit)
            {
                Mallory.Draw(spriteBatch, Color.White, 1.0f, spriteEffect);
            }
            else
            {
                Mallory.Draw(spriteBatch, Color.Red, 1.0f, spriteEffect);
            }

            if (!b_RequestAbilityOneActivate)
            {
                spriteBatch.Draw(t2d_DarknessOverlay, v2_position, null, Color.White, 1.0f, v2_DarknessOrigin, 1.0f, spriteEffect, 1.0f);
            }

        }

    }
}
